home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_Menu_.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-06  |  5.0 KB  |  177 lines

  1. //
  2. // "$Id: Fl_Menu_.cxx,v 1.7.2.5 1999/05/06 06:20:46 bill Exp $"
  3. //
  4. // Common menu code for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. // This is a base class for all items that have a menu:
  27. //    Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice
  28. // This provides storage for a menu item, functions to add/modify/delete
  29. // items, and a call for when the user picks a menu item.
  30.  
  31. // More code in Fl_Menu_add.C
  32.  
  33. #include <FL/Fl.H>
  34. #include <FL/Fl_Menu_.H>
  35. #include <string.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38.  
  39. int Fl_Menu_::value(const Fl_Menu_Item* m) {
  40.   clear_changed();
  41.   if (value_ != m) {value_ = m; return 1;}
  42.   return 0;
  43. }
  44.  
  45. // When user picks a menu item, call this.  It will do the callback.
  46. // Unfortunatly this also casts away const for the checkboxes, but this
  47. // was necessary so non-checkbox menus can really be declared const...
  48. const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
  49.   if (v) {
  50.     if (v->radio()) {
  51.       if (!v->value()) { // they are turning on a radio item
  52.     set_changed();
  53.     ((Fl_Menu_Item*)v)->setonly();
  54.       }
  55.       redraw();
  56.     } else if (v->flags & FL_MENU_TOGGLE) {
  57.       set_changed();
  58.       ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE;
  59.       redraw();
  60.     } else if (v != value_) { // normal item
  61.       set_changed();
  62.     }
  63.     value_ = v;
  64.     if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) {
  65.       if (changed() || when()&FL_WHEN_NOT_CHANGED) {
  66.     clear_changed();
  67.     if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this);
  68.     else do_callback();
  69.       }
  70.     }
  71.   }
  72.   return v;
  73. }
  74.  
  75. // turn on one of a set of radio buttons
  76. void Fl_Menu_Item::setonly() {
  77.   flags |= FL_MENU_RADIO | FL_MENU_VALUE;
  78.   Fl_Menu_Item* j;
  79.   for (j = this; ; ) {    // go down
  80.     if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines
  81.     j++;
  82.     if (!j->text || !j->radio()) break; // stop after group
  83.     j->clear();
  84.   }
  85.   for (j = this-1; ; j--) { // go up
  86.     if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break;
  87.     j->clear();
  88.   }
  89. }
  90.  
  91. Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l)
  92. : Fl_Widget(X,Y,W,H,l) {
  93.   set_flag(SHORTCUT_LABEL);
  94.   box(FL_UP_BOX);
  95.   when(FL_WHEN_RELEASE_ALWAYS);
  96.   value_ = menu_ = 0;
  97.   alloc = 0;
  98.   selection_color(FL_SELECTION_COLOR);
  99.   textfont(FL_HELVETICA);
  100.   textsize(FL_NORMAL_SIZE);
  101.   textcolor(FL_BLACK);
  102.   down_box(FL_NO_BOX);
  103. }
  104.  
  105. int Fl_Menu_::size() const {
  106.   if (!menu_) return 0;
  107.   return menu_->size();
  108. }
  109.  
  110. void Fl_Menu_::menu(const Fl_Menu_Item* m) {
  111.   clear();
  112.   value_ = menu_ = (Fl_Menu_Item*)m;
  113. }
  114.  
  115. #if 1
  116. // this version is ok with new Fl_Menu_add code with fl_menu_array_owner:
  117.  
  118. void Fl_Menu_::copy(const Fl_Menu_Item* m, void* user_data) {
  119.   int n = m->size();
  120.   Fl_Menu_Item* newMenu = new Fl_Menu_Item[n];
  121.   memcpy(newMenu, m, n*sizeof(Fl_Menu_Item));
  122.   menu(newMenu);
  123.   alloc = 1; // make destructor free array, but not strings
  124.   // for convienence, provide way to change all the user data pointers:
  125.   if (user_data) for (; n--;) {
  126.     if (newMenu->callback_) newMenu->user_data_ = user_data;
  127.     newMenu++;
  128.   }
  129. }
  130.  
  131. #else
  132. // This is Guillaume Nodet's fixed version for the older Fl_Menu_add
  133. // that enlarged the array at powers of 2:
  134.  
  135. void Fl_Menu_::copy(const Fl_Menu_Item* m, void* user_data) {
  136.   int i, s = m->size(), n=s;
  137.   for (i=0; n; n>>=1, i++);
  138.   n = 1 << i;
  139.   Fl_Menu_Item* newMenu = new Fl_Menu_Item[n];
  140.   memcpy(newMenu, m, s*sizeof(Fl_Menu_Item));
  141.   memset(newMenu+s, 0, (n-s)*sizeof(Fl_Menu_Item));
  142.   menu(newMenu);
  143.   alloc = 1; // make destructor free it
  144.   // for convienence, provide way to change all the user data pointers:
  145.   if (user_data) for (; s--;) {
  146.     if (newMenu->callback_) newMenu->user_data_ = user_data;
  147.     newMenu++;
  148.   }
  149. }
  150. #endif
  151.  
  152. Fl_Menu_::~Fl_Menu_() {
  153.   clear();
  154. }
  155.  
  156. // Fl_Menu::add() uses this to indicate the owner of the dynamically-
  157. // expanding array.  We must not free this array:
  158. Fl_Menu_* fl_menu_array_owner = 0;
  159.  
  160. void Fl_Menu_::clear() {
  161.   if (alloc) {
  162.     if (alloc>1) for (int i = size(); i--;)
  163.       if (menu_[i].text) free((void*)menu_[i].text);
  164.     if (this == fl_menu_array_owner)
  165.       fl_menu_array_owner = 0;
  166.     else
  167.       delete[] menu_;
  168.     menu_ = 0;
  169.     value_ = 0;
  170.     alloc = 0;
  171.   }
  172. }
  173.  
  174. //
  175. // End of "$Id: Fl_Menu_.cxx,v 1.7.2.5 1999/05/06 06:20:46 bill Exp $".
  176. //
  177.